<template>
  <div class="app-container">
    <el-card>
      <template #header>
        <div class="card-header">
          <span>操作日志管理</span>
          <div>
            <el-button type="danger" @click="handleClearLogs">
              <el-icon><Delete /></el-icon> 清空日志
            </el-button>
            <el-button type="primary" @click="refreshLogs">
              <el-icon><Refresh /></el-icon> 刷新
            </el-button>
          </div>
        </div>
      </template>

      <!-- 统计信息 -->
      <el-row :gutter="20" class="mb-4">
        <el-col :span="6">
          <el-card shadow="hover" class="stat-card">
            <template #header>
              <div class="stat-card-header">总操作次数</div>
            </template>
            <div class="stat-card-content">
              <div class="stat-number">{{ logStats.total || 0 }}</div>
              <div class="stat-icon">
                <el-icon><Document /></el-icon>
              </div>
            </div>
          </el-card>
        </el-col>
        <el-col :span="6">
          <el-card shadow="hover" class="stat-card success-card">
            <template #header>
              <div class="stat-card-header">成功操作</div>
            </template>
            <div class="stat-card-content">
              <div class="stat-number">{{ logStats.success || 0 }}</div>
              <div class="stat-icon">
                <el-icon><Select /></el-icon>
              </div>
            </div>
          </el-card>
        </el-col>
        <el-col :span="6">
          <el-card shadow="hover" class="stat-card error-card">
            <template #header>
              <div class="stat-card-header">失败操作</div>
            </template>
            <div class="stat-card-content">
              <div class="stat-number">{{ logStats.fail || 0 }}</div>
              <div class="stat-icon">
                <el-icon><WarningFilled /></el-icon>
              </div>
            </div>
          </el-card>
        </el-col>
        <el-col :span="6">
          <el-card shadow="hover" class="stat-card">
            <template #header>
              <div class="stat-card-header">今日操作</div>
            </template>
            <div class="stat-card-content">
              <div class="stat-number">{{ logStats.today || 0 }}</div>
              <div class="stat-icon">
                <el-icon><Calendar /></el-icon>
              </div>
            </div>
          </el-card>
        </el-col>
      </el-row>

      <!-- 搜索表单 -->
      <el-form :inline="true" :model="queryParams" class="search-form">
        <el-form-item label="操作用户">
          <el-input v-model="queryParams.username" placeholder="请输入操作用户" clearable @keyup.enter="searchLogs" />
        </el-form-item>
        <el-form-item label="操作模块">
          <el-select v-model="queryParams.module" placeholder="请选择操作模块" clearable>
            <el-option label="用户管理" value="用户管理" />
            <el-option label="角色管理" value="角色管理" />
            <el-option label="设备管理" value="设备管理" />
            <el-option label="设备组管理" value="设备组管理" />
            <el-option label="数据管理" value="数据管理" />
            <el-option label="系统管理" value="系统管理" />
          </el-select>
        </el-form-item>
        <el-form-item label="操作类型">
          <el-select v-model="queryParams.type" placeholder="请选择操作类型" clearable>
            <el-option label="查询" value="查询" />
            <el-option label="新增" value="新增" />
            <el-option label="修改" value="修改" />
            <el-option label="删除" value="删除" />
            <el-option label="授权" value="授权" />
            <el-option label="导出" value="导出" />
            <el-option label="导入" value="导入" />
            <el-option label="强退" value="强退" />
            <el-option label="清空" value="清空" />
          </el-select>
        </el-form-item>
        <el-form-item label="操作状态">
          <el-select v-model="queryParams.status" placeholder="请选择操作状态" clearable>
            <el-option label="成功" :value="1" />
            <el-option label="失败" :value="0" />
          </el-select>
        </el-form-item>
        <el-form-item label="操作时间">
          <el-date-picker
            v-model="dateRange"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            value-format="YYYY-MM-DD"
            :shortcuts="dateShortcuts"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="searchLogs">
            <el-icon><Search /></el-icon> 搜索
          </el-button>
          <el-button @click="resetQuery">
            <el-icon><Refresh /></el-icon> 重置
          </el-button>
        </el-form-item>
      </el-form>

      <!-- 日志表格 -->
      <el-table v-loading="loading" :data="logList" border>
        <el-table-column prop="id" label="日志编号" width="80" />
        <el-table-column prop="username" label="操作用户" width="100" />
        <el-table-column prop="module" label="操作模块" width="100" />
        <el-table-column prop="type" label="操作类型" width="80" />
        <el-table-column prop="action" label="操作内容" show-overflow-tooltip />
        <el-table-column prop="url" label="请求地址" width="150" show-overflow-tooltip />
        <el-table-column prop="method" label="请求方式" width="80" />
        <el-table-column prop="ip" label="操作IP" width="120" />
        <el-table-column label="操作状态" width="80">
          <template #default="scope">
            <el-tag :type="row.status === 1 ? 'success' : 'danger'">
              {{ row.status === 1 ? '成功' : '失败' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="create_time" label="操作时间" width="180" />
        <el-table-column label="操作" width="130">
          <template #default="scope">
            <el-button type="primary" size="small" @click="showDetail(row)">
              <el-icon><View /></el-icon> 详情
            </el-button>
            <el-button type="danger" size="small" @click="handleDelete(row.id)">
              <el-icon><Delete /></el-icon> 删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <el-pagination
        v-if="total > 0"
        class="pagination"
        :current-page="queryParams.page"
        :page-sizes="[10, 20, 50, 100]"
        :page-size="queryParams.pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </el-card>

    <!-- 日志详情对话框 -->
    <el-dialog v-model="dialogVisible" title="操作日志详情" width="700px">
      <el-descriptions :column="2" border>
        <el-descriptions-item label="操作编号" :span="2">{{ logDetail.id }}</el-descriptions-item>
        <el-descriptions-item label="操作用户">{{ logDetail.username }}</el-descriptions-item>
        <el-descriptions-item label="操作时间">{{ logDetail.create_time }}</el-descriptions-item>
        <el-descriptions-item label="操作模块">{{ logDetail.module }}</el-descriptions-item>
        <el-descriptions-item label="操作类型">{{ logDetail.type }}</el-descriptions-item>
        <el-descriptions-item label="操作内容" :span="2">{{ logDetail.action }}</el-descriptions-item>
        <el-descriptions-item label="请求地址" :span="2">{{ logDetail.url }}</el-descriptions-item>
        <el-descriptions-item label="请求方式">{{ logDetail.method }}</el-descriptions-item>
        <el-descriptions-item label="操作IP">{{ logDetail.ip }}</el-descriptions-item>
        <el-descriptions-item label="操作状态">
          <el-tag :type="logDetail.status === 1 ? 'success' : 'danger'">
            {{ logDetail.status === 1 ? '成功' : '失败' }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="操作结果">
          <el-tag :type="logDetail.status === 1 ? 'success' : 'danger'">
            {{ logDetail.response || (logDetail.status === 1 ? '操作成功' : '操作失败') }}
          </el-tag>
        </el-descriptions-item>
      </el-descriptions>

      <template v-if="logDetail.params">
        <div class="mt-4">
          <div class="detail-title">请求参数</div>
          <pre class="detail-content">{{ formatJson(logDetail.params) }}</pre>
        </div>
      </template>

      <template v-if="logDetail.error">
        <div class="mt-4">
          <div class="detail-title">错误信息</div>
          <pre class="detail-content error-content">{{ logDetail.error }}</pre>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, watch, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  getOperationLogs,
  getOperationLogDetail,
  deleteOperationLog,
  clearOperationLogs,
  getOperationLogStats
} from '@/api/system'
import {
  Document, Select, WarningFilled, Calendar, Search,
  Refresh, Delete, View
} from '@element-plus/icons-vue'

// 日志列表数据
const logList = ref([])
const total = ref(0)
const loading = ref(false)

// 日志统计信息
const logStats = ref({})

// 查询参数
const queryParams = reactive({
  username: '',
  module: '',
  type: '',
  status: '',
  begin_time: '',
  end_time: '',
  page: 1,
  pageSize: 10
})

// 日期范围
const dateRange = ref([])

// 日期快捷选项
const dateShortcuts = [
  {
    text: '最近一周',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
      return [start, end]
    }
  },
  {
    text: '最近一个月',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
      return [start, end]
    }
  },
  {
    text: '最近三个月',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
      return [start, end]
    }
  }
]

// 详情对话框
const dialogVisible = ref(false)
const logDetail = ref({})

// 监听日期范围变化
watch(dateRange, (val) => {
  queryParams.begin_time = val && val.length > 0 ? val[0] : ''
  queryParams.end_time = val && val.length > 0 ? val[1] : ''
})

// 初始化
onMounted(() => {
  getLogs()
  getStats()
})

// 获取日志列表
const getLogs = async () => {
  loading.value = true
  try {
    const res = await getOperationLogs(queryParams)
    logList.value = res.data.data
    total.value = res.data.total
  } catch (error) {
    console.error(error)
    ElMessage.error('获取操作日志失败')
  } finally {
    loading.value = false
  }
}

// 获取统计信息
const getStats = async () => {
  try {
    const res = await getOperationLogStats()
    logStats.value = res.data
  } catch (error) {
    console.error(error)
    ElMessage.error('获取统计信息失败')
  }
}

// 刷新日志
const refreshLogs = () => {
  getLogs()
  getStats()
}

// 搜索日志
const searchLogs = () => {
  queryParams.page = 1
  getLogs()
}

// 重置查询
const resetQuery = () => {
  queryParams.username = ''
  queryParams.module = ''
  queryParams.type = ''
  queryParams.status = ''
  dateRange.value = []
  queryParams.begin_time = ''
  queryParams.end_time = ''
  queryParams.page = 1
  getLogs()
}

// 处理每页条数变化
const handleSizeChange = (size) => {
  queryParams.pageSize = size
  getLogs()
}

// 处理页码变化
const handleCurrentChange = (page) => {
  queryParams.page = page
  getLogs()
}

// 显示日志详情
const showDetail = async (row) => {
  try {
    const res = await getOperationLogDetail(row.id)
    logDetail.value = res.data
    dialogVisible.value = true
  } catch (error) {
    console.error(error)
    ElMessage.error('获取日志详情失败')
  }
}

// 删除单条日志
const handleDelete = (id) => {
  ElMessageBox.confirm('确定要删除该操作日志吗？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    try {
      const res = await deleteOperationLog(id)
      ElMessage.success(res.msg || '删除成功')
      getLogs()
      getStats()
    } catch (error) {
      console.error(error)
      ElMessage.error('删除失败')
    }
  }).catch(() => {})
}

// 清空日志
const handleClearLogs = () => {
  ElMessageBox.confirm('确定要清空所有操作日志吗？此操作不可恢复！', '警告', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    try {
      const res = await clearOperationLogs()
      ElMessage.success(res.msg || '清空成功')
      getLogs()
      getStats()
    } catch (error) {
      console.error(error)
      ElMessage.error('清空失败')
    }
  }).catch(() => {})
}

// 格式化JSON
const formatJson = (json) => {
  try {
    const jsonObj = typeof json === 'string' ? JSON.parse(json) : json
    return JSON.stringify(jsonObj, null, 2)
  } catch (error) {
    return json
  }
}
</script>

<style scoped>
.app-container {
  padding: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.mb-4 {
  margin-bottom: 15px;
}

.mt-4 {
  margin-top: 15px;
}

.pagination {
  margin-top: 15px;
  display: flex;
  justify-content: flex-end;
}

/* 统计卡片样式 */
.stat-card {
  height: 150px;
  position: relative;
  overflow: hidden;
}

.stat-card-header {
  font-size: 16px;
  font-weight: bold;
  color: #606266;
}

.stat-card-content {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 10px;
}

.stat-number {
  font-size: 32px;
  font-weight: bold;
  color: #409EFF;
}

.success-card .stat-number {
  color: #67C23A;
}

.error-card .stat-number {
  color: #F56C6C;
}

.stat-icon {
  font-size: 42px;
  opacity: 0.2;
  color: #909399;
}

/* 搜索表单样式 */
.search-form {
  margin-bottom: 15px;
}

/* 详情样式 */
.detail-title {
  font-weight: bold;
  margin-bottom: 10px;
  color: #606266;
}

.detail-content {
  background-color: #f8f8f9;
  padding: 10px;
  border-radius: 4px;
  max-height: 300px;
  overflow-y: auto;
  font-family: monospace;
  font-size: 14px;
  white-space: pre-wrap;
}

.error-content {
  background-color: #fef0f0;
  color: #f56c6c;
}
</style> 